<template>
  <div :class="`select ${className}`" :style="style">
    <div
      class="select-selected"
      :class="open ? 'open' : 'close'"
      @click.stop="handleOpen"
    >
      {{ selectData.label }}
    </div>
    <div
      class="select-option-list"
      :id="`select-options-${id}`"
      :class="open ? 'open' : 'close'"
      @click="handleOptionClick"
    >
      <slot>
        <Item v-for="item in options" :key="item.value" :label="item.label" :value="item.value" :selected="item.value == value" />
      </slot>
    </div>
  </div>
</template>

<script >
import Item from "./Item.vue";
import { ref, reactive, onMounted, toRaw } from "vue";

export default {
  components: { Item },
  props: {
    /**
     * 下拉列表数据，非必传可使用 Select.Item 替换
     */
    options: {
      type: Array,
      default: () => []
    },
    /**
     * 下拉选择回调
     */
    change: {
      type: Function,
      required: false,
    },
    /**、
     * 当前选中值
     */
    value: {
      type: [Number, String],
      required: false,
    },
    /**
     * 自定义样式对象
     */
    style: {
      type: Object,
      default: () => ({}),
    },
    /**
     * 自定义类名，可用于自定义样式
     */
    className: {
      type: String,
      default: '',
    },
  },
  setup(props, ctx) {
    const open = ref(false);
    const selectData = reactive({ label: "", value: "" });
    const id = new Date().getTime()

    const handleOpen = () => {
      open.value = !open.value;
    };

    const handleOptionClick = (e) => {
      open.value = false;
      const value = e.target.dataset.value;
      const label = e.target.dataset.label || e.target.innerHTML;

      selectData.value = value;
      selectData.label = label;
      ctx.emit("update:value", value);
      ctx.emit("change", value, toRaw(selectData));
    };

    onMounted(() => {
      if (Array.isArray(props.options) && props.options.length) {
        for (let i = 0; i < props.options.length; i++) {
          const item = props.options[i];
          if (item.value == props.value) {
            selectData.value = item.value;
            selectData.label = item.label;
            break;
          }
        }
      } else {
        const optionsEl = document.querySelector(`#select-options-${id}`)
        const options = Array.from(optionsEl.children)
        options.forEach(item => {
          if(item.dataset.value == props.value) {
            selectData.value = item.dataset.value;
            selectData.label = item.dataset.label || item.innerHTML;
          }
        })
      }
      document.addEventListener("click", () => {
        open.value = false;
      });
    });

    return {
      id,
      open,
      selectData,
      handleOpen,
      handleOptionClick,
    };
  },
};
</script>

<style scoped>
.select {
  width: 400px;
  position: relative;
}
.select-selected {
  height: 40px;
  line-height: 40px;
  border: 1px solid rgb(223, 222, 222);
  border-radius: 3px;
  position: relative;
  padding-left: 10px;
  padding-right: 40px;
}
.select-selected:hover {
  border-color: rgba(14, 106, 245, 0.9);
  cursor: pointer;
}
.select-selected::after {
  content: "";
  display: block;
  width: 10px;
  height: 10px;
  background-image: url("./arrow.png");
  background-size: cover;
  position: absolute;
  right: 10px;
  top: 50%;
  margin-top: -5px;
  transition: all 0.3s;
}
.select-selected.close::after {
  transform: rotate(0);
}
.select-selected.open::after {
  transform: rotate(180deg);
}
.select-option-list {
  box-shadow: 0 0 2px rgb(207, 207, 207);
  border-radius: 3px;
  overflow: hidden;
  transition: all 0.2s;
  position: absolute;
  top: 43px;
  width: 100%;
  background-color: white;
  z-index: 90;
}
.select-option-list.open {
  display: block;
}
.select-option-list.close {
  display: none;
}
</style>